<!DOCTYPE html>
<script src='../resources/testharness.js'></script>
<script src='../resources/testharnessreport.js'></script>

<script>
var EPSILON = 1e-6; // float epsilon

let angleUnits = [
  'deg',
  'rad',
  'grad',
  'turn'
];

let fixedLengthUnits = [
  'px',
  'in',
  'cm',
  'mm',
  'pt',
  'pc'
];

let conversionFactors = {
  'deg': {
    'deg': 1,
    'rad': Math.PI / 180,
    'grad': 400 / 360,
    'turn': 1 / 360,
  },
  'rad': {
    'deg': 180 / Math.PI,
    'rad': 1,
    'grad': 200 / Math.PI,
    'turn': 0.5 / Math.PI,
  },
  'grad': {
    'deg': 360 / 400,
    'rad': Math.PI / 200,
    'grad': 1,
    'turn': 1 / 400,
  },
  'turn': {
    'deg': 360,
    'rad': 2 * Math.PI,
    'grad': 400,
    'turn': 1,
  },
  // 96 px per in
  // 2.54 cm per in
  // 10 mm per cm
  // 72 pt per in
  // 6 pc per in
  'px': {
    'px': 1,
    'in': 1 / 96,
    'cm': 2.54 / 96,
    'mm': 25.4 / 96,
    'pt': 72 / 96,
    'pc': 6 / 96
  },
  'in': {
    'px': 96,
    'in': 1,
    'cm': 2.54,
    'mm': 25.4,
    'pt': 72,
    'pc': 6
  },
  'cm': {
    'px': 96 / 2.54,
    'in': 1 / 2.54,
    'cm': 1,
    'mm': 10,
    'pt': 72 / 2.54,
    'pc': 6 / 2.54
  },
  'mm': {
    'px': 96 / 25.4,
    'in': 1 / 25.4,
    'cm': 1 / 10,
    'mm': 1,
    'pt': 72 / 25.4,
    'pc': 6 / 25.4
  },
  'pt': {
    'px': 96 / 72,
    'in': 1 / 72,
    'cm': 2.54 / 72,
    'mm': 25.4 / 72,
    'pt': 1,
    'pc': 6 / 72,
  },
  'pc': {
    'px': 96 / 6,
    'in': 1 / 6,
    'cm': 2.54 / 6,
    'mm': 25.4 / 6,
    'pt': 72 / 6,
    'pc': 1
  }
}

test(() => {
  let unitValue = new CSSUnitValue(1, 'deg');
  assert_throws_dom("SyntaxError", () => {
    unitValue.to('bananas');
  });
}, 'Converting to invalid unit throws');

test(() => {
  let unitValue = new CSSUnitValue(1, 'deg');
  assert_throws_js(TypeError, () => {
    unitValue.to('px');
  });
}, 'Converting to a non-compatible unit throws');

for (let unit of angleUnits) {
  for (let toUnit of angleUnits) {
    test(() => {
      let unitValue = new CSSUnitValue(1, unit);
      let result = unitValue.to(toUnit);
      assert_approx_equals(
          result.value, conversionFactors[unit][toUnit], EPSILON);
      assert_equals(result.unit, toUnit);
    }, 'Converting angle unit ' + unit + ' to ' + toUnit);
  }
}

for (let unit of fixedLengthUnits) {
  for (let toUnit of fixedLengthUnits) {
    test(() => {
      let unitValue = new CSSUnitValue(1, unit);
      let result = unitValue.to(toUnit);
      assert_approx_equals(
          result.value, conversionFactors[unit][toUnit], EPSILON);
      assert_equals(result.unit, toUnit);
    }, 'Converting fixed length unit ' + unit + ' to ' + toUnit);
  }
}

</script>
